/*
 * PgmFileUtils.h
 *
 *  Created on: Nov 29, 2009
 */

#ifndef PGMFILEUTILS_H_
#define PGMFILEUTILS_H_

#include <fstream>
#include "../../common/utils/StringUtils.h"
#include "../impl/PgmImageEntity.h"
#include "../../common/exception/SystemException.h"

class PgmFileUtils {
private:
	/*
	 * @postcondition	height and width
	 */
	static void readWidthAndHeight(int count, string line, int &width, int &height) {
        if(count == 2) {
            vector<string> widthAndHeight = StringUtils::split(StringUtils::trim(line), " ");
            if(widthAndHeight.size() == 2){
            	width = atoi(widthAndHeight[0].c_str());
            	height = atoi(widthAndHeight[1].c_str());
            }
        }
    }
public:

	/*
	 *	@precondition	path is valid PGM path
	 */
	static PgmImageEntity *read(string path) {
		int height = 0;
		int width = 0;
		int **vectors;

		ifstream in(path.c_str());

		if (in.is_open()) {
			int count = 0;
			int lineVector = 0;
			int columnVector = 0;

			while (!in.eof()) {
				string line;
				getline(in, line);

				if (StringUtils::isEmpty(line) || line.find("#") == 0) {
					continue;
				} else {
					count++;
				}

				if(count == 2) {
					readWidthAndHeight(count, line, width, height);
					vectors = new int*[height];
					for (int i = 0; i < height; i++) {
						vectors[i] = new int[width];
					}
				}

				if (count > 3) {
					vector<string> currentLine = StringUtils::split(StringUtils::trim(line), " ");
					vector<string>::iterator i = currentLine.begin();
					while (i != currentLine.end()) {
						string value = *i;

						if (lineVector == width) {
							lineVector = 0;
							columnVector++;
						}

						vectors[columnVector][lineVector] = atoi(value.c_str());
						lineVector++;

						i++;
					}
				}
			}

			in.close();
		} else {
			throw SystemException("error.pgm.not.found: " + path);
		}

		return new PgmImageEntity(width, height, vectors);
	}

	static void save(string imagePath, ImageEntity *imageEntity) {
		ofstream out;
		out.open(imagePath.c_str());

		out << "P2" << endl;
		out << imageEntity->getWidth() << " ";
		out << imageEntity->getHeight() << endl;
		out << imageEntity->getWidth() << endl;

		for (int i = 0; i < imageEntity->getHeight(); i++) {
			for (int j = 0; j < imageEntity->getWidth(); j++) {
				out << imageEntity->getVectorsR()[i][j];
				out << " ";
			}

			out << endl;
		}

		out.close();
	}
};

#endif /* PGMFILEUTILS_H_ */
